home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / macabuse / src / unixnfc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-20  |  16.3 KB  |  656 lines

  1. #include "system.h"
  2. #include "indian.hpp"
  3. #include <sys/types.h>
  4. #include <sys/ipc.h>
  5. #include <sys/shm.h>
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <signal.h>
  10. #include <unistd.h>
  11. #include <sys/fcntl.h>
  12. #include <fcntl.h>
  13.  
  14.  
  15. #include "netface.hpp"
  16. #include "nfserver.hpp"
  17. #include "view.hpp"
  18. #include "objects.hpp"
  19. #include "level.hpp"
  20. #include "timing.hpp"
  21. #include "server2.hpp"
  22. #include "game.hpp"
  23. #include "jwindow.hpp"
  24.  
  25. extern char lsf[256];
  26.  
  27. #define DIN_NAME "/tmp/.abuse_ndrv_out"   // opposite of driver's in/out
  28. #define DOUT_NAME "/tmp/.abuse_ndrv_in"
  29.  
  30. #define uchar unsigned char
  31. #define ushort unsigned short
  32.  
  33. #define real2shm(type,ptr) (ptr==NULL ? NULL : ((type *)((char *)(ptr)-(char *)base)))
  34. #define shm2real(type,ptr) (ptr==NULL ? NULL : ((type *)((long)(ptr)+(long)(base))))
  35.  
  36. #ifdef __sgi
  37. #define next_process() sginap(0)
  38. #else
  39. #define next_process() usleep(1)
  40. #endif
  41.  
  42. extern int crc_man_write_crc_file(char *filename);
  43. int net_installed=0,net_out_fd,net_in_fd;
  44. int net_child=-1;
  45. int local_client_number=0;
  46.  
  47. void *shm_addr=(void *)-1;  // shmat returns -1 on failure
  48. base_memory_struct *base;   // points to shm_addr
  49. base_memory_struct local_base;
  50.  
  51. net_address *net_server=NULL;
  52.  
  53. extern int registered;
  54.  
  55. int net_start() 
  56.   return net_server!=NULL; 
  57. }
  58.  
  59.  
  60. int kill_net()
  61. {
  62.  
  63.   if (net_installed)
  64.   {
  65.     char cmd=EGCMD_DIE;
  66.     write(net_out_fd,&cmd,1);
  67.     read(net_in_fd,&cmd,1);
  68.     close(net_out_fd);
  69.     close(net_in_fd);
  70.   }
  71.  
  72.   if (net_child!=-1)
  73.   {
  74.     kill(net_child,SIGINT);
  75.     net_child=-1;    
  76.   }
  77.  
  78.   net_installed=0;
  79.   if (shm_addr!=(void *)-1)
  80.   {
  81.     shmdt((char *)shm_addr);
  82.     shm_addr=(void *)-1;
  83.     base=&local_base;
  84.   }
  85. }
  86.  
  87. void net_uninit()
  88. {
  89.   kill_net();
  90. }
  91.  
  92. int net_init(int argc, char **argv)
  93. {
  94.   int i,p1=-1,no_fork=0;
  95.   base=&local_base;
  96.   char *server_name=NULL;
  97.  
  98.   for (i=1;i<argc;i++) 
  99.     if (!strcmp(argv[i],"-nonet"))
  100.       return 0;
  101.     else if (!strcmp(argv[i],"-no_net_fork"))      // make it easy to run the driver under a debugger
  102.       no_fork=1;
  103.     else if (!strcmp(argv[i],"-port"))
  104.     {
  105.       if (i==argc-1 || !sscanf(argv[i+1],"%d",&p1))
  106.       {
  107.         fprintf(stderr,"bad value folloing -port");
  108.     return 0;
  109.       }
  110.     } else if (!strcmp(argv[i],"-net") && i<argc-1)
  111.     {
  112.       i++;
  113.       server_name=argv[i];      
  114.     }
  115.  
  116.       
  117.     
  118.   char cmd[50];
  119.   if (p1!=-1) 
  120.     sprintf(cmd,"undrv runme -port %d",p1);
  121.   else sprintf(cmd,"undrv runme");
  122.  
  123.   if (!no_fork)
  124.   {
  125.     FILE *fp=popen(cmd,"rb");
  126.     if (!fp || !fscanf(fp,"%d",&net_child) || net_child==-1)
  127.     { fprintf(stderr,"could not run undrv, please make sure it's in your path\n");
  128.       return 0;
  129.     }
  130.  
  131.     if (fp) pclose(fp);
  132.   }
  133.  
  134.   do
  135.   { sleep(0);
  136.   } while (access(DIN_NAME,R_OK)); 
  137.   net_in_fd=open(DIN_NAME,O_RDWR);
  138.  
  139.   do
  140.   { sleep(0);
  141.   } while (access(DOUT_NAME,W_OK)); 
  142.   net_out_fd=open(DOUT_NAME,O_RDWR);
  143.  
  144.  
  145.   if (write(net_out_fd,®istered,sizeof(registered))!=sizeof(registered))
  146.     return 0;
  147.  
  148.   int shm_seg_id;
  149.   if (read(net_in_fd,&shm_seg_id,sizeof(shm_seg_id))!=sizeof(shm_seg_id))
  150.     return 0;
  151.  
  152.   shm_addr=shmat(shm_seg_id,NULL,0);  // attach as read/write
  153.   if (shm_addr==(void *)-1)
  154.     return 0;
  155.  
  156.   char ack=1;   // acknodge we read and attached
  157.   if (write(net_out_fd,&ack,1)!=1)
  158.     return 0;  
  159.  
  160.  
  161.   base=(base_memory_struct *)shm_addr;
  162.  
  163.   net_installed=1;
  164.       
  165.   return 1;
  166. }
  167.  
  168. #include <unistd.h>
  169. #include <sys/time.h>
  170.  
  171. int NF_set_file_server(char *name)
  172. {
  173.   if (net_installed)
  174.   {
  175.     char cm[2]={NFCMD_SET_FS,strlen(name)+1};
  176.     if (write(net_out_fd,cm,2)!=2) { kill_net(); return 0; }
  177.     if (write(net_out_fd,name,cm[1])!=cm[1]) { kill_net(); return 0; }
  178.     if (read(net_in_fd,cm,1)!=1)  { kill_net(); return 0; }   // read the status of this command
  179.     next_process();
  180.     return cm[0];
  181.   } else return 0; 
  182. }
  183.  
  184. int NF_open_file(char *filename, char *mode)
  185. {
  186.   if (net_installed)
  187.   {
  188.     char cm[3]={NFCMD_OPEN,strlen(filename)+1,strlen(mode)+1};
  189.     if (write(net_out_fd,cm,3)!=3) { kill_net(); return -1; }
  190.     if (write(net_out_fd,filename,cm[1])!=cm[1])  { kill_net(); return -1; }
  191.     if (write(net_out_fd,mode,cm[2])!=cm[2])  { kill_net(); return -1; }
  192.  
  193.     uchar file_type;
  194.     if (read(net_in_fd,&file_type,1)!=1)  { kill_net(); return -1; }    
  195.     if (file_type==NF_OPEN_LOCAL_FILE) 
  196.     {
  197.       uchar name_size;
  198.       if (read(net_in_fd,&name_size,1)!=1)  { kill_net(); return -1; }          
  199.       int size=read(net_in_fd,filename,name_size);
  200.       if (size!=name_size)  { kill_net(); return -1; }    
  201.       return -2;
  202.     }
  203.     else if (file_type==NF_OPEN_FAILED) return -1;
  204.  
  205.     int fd;
  206.     if (read(net_in_fd,&fd,sizeof(fd))!=sizeof(fd))  { kill_net(); return -1; }
  207.  
  208.     return fd;
  209.   } else return -2;          // return open local
  210. }
  211.  
  212. long NF_close(int fd)
  213. {
  214.   if (net_installed)
  215.   {
  216.     char cm=NFCMD_CLOSE;
  217.     if (write(net_out_fd,&cm,1)!=1) { kill_net(); return 0; }
  218.     if (write(net_out_fd,&fd,sizeof(fd))!=sizeof(fd)) { kill_net(); return 0; }
  219.     char stat;
  220.     if (read(net_in_fd,&stat,sizeof(stat))!=sizeof(stat))  { kill_net(); return 0; }
  221.     return stat;
  222.   } else return 0;  
  223. }
  224.  
  225.  
  226. long NF_read(int fd, void *buf, long size)
  227. {
  228.   if (net_installed && size)
  229.   {
  230.     char cm=NFCMD_READ;
  231.  
  232.     if (write(net_out_fd,&cm,1)!=1) { kill_net(); return 0; }
  233.     if (write(net_out_fd,&fd,sizeof(fd))!=sizeof(fd)) { kill_net(); return 0; }
  234.     if (write(net_out_fd,&size,sizeof(size))!=sizeof(size)) { kill_net(); return 0; }
  235.  
  236.     long total_read=0;
  237.     ushort t=0xffff;
  238.     while (size && t>=READ_PACKET_SIZE-2)
  239.     {
  240.       if (read(net_in_fd,&t,sizeof(t))!=sizeof(t))  { kill_net(); return 0; }      
  241.       if (read(net_in_fd,buf,t)!=t)  { kill_net(); return total_read; }
  242.  
  243.       total_read+=t;
  244.       size-=t;
  245.       buf=(void *)((char *)buf+t);
  246.  
  247.  
  248.     }
  249.     return total_read;
  250.   } else return 0;  
  251. }
  252.  
  253.  
  254. long NF_filelength(int fd)
  255. {
  256.   if (net_installed)
  257.   {
  258.     char cm=NFCMD_SIZE;
  259.     if (write(net_out_fd,&cm,1)!=1) { kill_net(); return 0; }
  260.     if (write(net_out_fd,&fd,sizeof(fd))!=sizeof(fd)) { kill_net(); return 0; }
  261.     long size;
  262.     if (read(net_in_fd,&size,sizeof(size))!=sizeof(size))  { kill_net(); return 0; }
  263.     return size;
  264.   } else return 0;  
  265. }
  266.  
  267. long NF_tell(int fd)
  268. {
  269.   if (net_installed)
  270.   {
  271.     char cm=NFCMD_TELL;
  272.     if (write(net_out_fd,&cm,1)!=1) { kill_net(); return 0; }
  273.     if (write(net_out_fd,&fd,sizeof(fd))!=sizeof(fd)) { kill_net(); return 0; }
  274.     long offset;
  275.     if (read(net_in_fd,&offset,sizeof(offset))!=sizeof(offset))  { kill_net(); return 0; }
  276.     return offset;
  277.   } else return 0;  
  278. }
  279.  
  280. long NF_seek(int fd, long offset)
  281. {
  282.   if (net_installed)
  283.   {
  284.     char cm=NFCMD_SEEK;
  285.     if (write(net_out_fd,&cm,1)!=1) { kill_net(); return 0; }
  286.     if (write(net_out_fd,&fd,sizeof(fd))!=sizeof(fd)) { kill_net(); return 0; }
  287.     if (write(net_out_fd,&offset,sizeof(offset))!=sizeof(offset)) { kill_net(); return 0; }
  288.  
  289.     long offset;
  290.     if (read(net_in_fd,&offset,sizeof(offset))!=sizeof(offset))  { kill_net(); return 0; }
  291.     return offset;
  292.   } else return 0;  
  293. }
  294.  
  295. static int aquire_mem_lock()
  296. {
  297.   if (base->mem_lock==0 || base->mem_lock==2)
  298.   {
  299.     base->mem_lock=2;
  300.     if (base->mem_lock==2)
  301.       return 1;
  302.   }
  303. //  next_process();   // probably just gonna loop until we get the lock so halt for next preocess
  304.   return 0;
  305. }
  306.  
  307. void service_net_request() 
  308. {
  309.   if (net_installed)
  310.   {
  311.     if (base->input_state==INPUT_NET_DEAD)
  312.       kill_net();
  313.     else
  314.     {
  315.       if (aquire_mem_lock())
  316.       {
  317.     if (base->calc_crcs)
  318.     {      
  319.       crc_man_write_crc_file(NET_CRC_FILENAME);       // return 0 on failure
  320.       base->calc_crcs=0;
  321.       base->mem_lock=0;
  322.  
  323.       uchar cmd=NFCMD_CRCS_CALCED;
  324.       if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return ; }
  325.     } else base->mem_lock=0;
  326.       }
  327.       if (aquire_mem_lock())
  328.       {
  329.     if (base->get_lsf)
  330.     {
  331.       base->get_lsf=0;
  332.       base->mem_lock=0;
  333.       uchar c[2]={NFCMD_PROCESS_LSF,strlen(lsf)+1};
  334.       if (write(net_out_fd,&c,2)!=2) { kill_net(); return ; }
  335.       if (write(net_out_fd,lsf,c[1])!=c[1]) { kill_net(); return ; }
  336.     } else base->mem_lock=0;
  337.       }
  338.     }
  339.   }
  340. }
  341.  
  342.  
  343. int get_remote_lsf(char *name, char *filename)  // filename should be 256 bytes
  344. {
  345.   if (net_installed)
  346.   {
  347.     uchar cm[2]={NFCMD_REQUEST_LSF,strlen(name)+1};
  348.     if (write(net_out_fd,cm,2)!=2) { kill_net(); return 0; }
  349.     if (write(net_out_fd,name,cm[1])!=cm[1]) { kill_net(); return 0; }
  350.     uchar size;
  351.     if (read(net_in_fd,&size,1)!=1) { kill_net(); return 0; }
  352.     if (size==0) return 0;
  353.     if (read(net_in_fd,filename,size)!=size) { kill_net(); return 0; }
  354.     return 1;  
  355.   } else return 0;
  356. }
  357.  
  358. int request_server_entry()
  359. {
  360.   if (net_installed)
  361.   {
  362.     if (!net_server) return 0;
  363.     uchar cm[2]={NFCMD_REQUEST_ENTRY,strlen(net_server)+1};
  364.     if (write(net_out_fd,cm,2)!=2) { kill_net(); return 0; }
  365.     if (write(net_out_fd,net_server,cm[1])!=cm[1]) { kill_net(); return 0; }
  366.     ushort cnum;  // client number
  367.     if (read(net_in_fd,&cnum,2)!=2) { kill_net(); return 0; } 
  368.     if (cnum==0) return 0;
  369.     local_client_number=cnum;
  370.     return 1;
  371.   } else return 0;
  372. }
  373.  
  374.  
  375. int reload_start()
  376. {
  377.   if (net_installed)
  378.   {
  379.     uchar cmd=NFCMD_RELOAD_START;
  380.     if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return 0; } 
  381.     if (read(net_in_fd,&cmd,1)!=1) { kill_net(); return 0; } 
  382.     return cmd;
  383.   } else return 1;
  384. }
  385.  
  386.  
  387. int reload_end()
  388. {
  389.   if (net_installed)
  390.   {
  391.     uchar cmd=NFCMD_RELOAD_END;
  392.     if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return 0; } 
  393.     if (read(net_in_fd,&cmd,1)!=1) { kill_net(); return 0; } 
  394.     return cmd;
  395.   } else return 1;
  396. }
  397.  
  398. void net_reload()
  399. {
  400.   if (net_installed)
  401.   {
  402.     if (net_server)
  403.     {
  404.       if (current_level)
  405.         delete current_level;
  406.       bFILE *fp;
  407.  
  408.       if (!reload_start()) return ;
  409.  
  410.       do {            // make sure server saves the file
  411.     fp=open_file(NET_STARTFILE,"rb");
  412.     if (fp->open_failure()) { delete fp; fp=NULL; }
  413.       } while (!fp);
  414.  
  415.       spec_directory sd(fp);  
  416.  
  417.       spec_entry *e=sd.find("Copyright 1995 Crack dot Com, All Rights reserved"); 
  418.       if (!e)
  419.       { 
  420.     the_game->show_help("This level is missing copyright information, cannot load\n");
  421.     current_level=new level(100,100,"untitled");
  422.     the_game->need_refresh();
  423.       }
  424.       else 
  425.         current_level=new level(&sd,fp,NET_STARTFILE);
  426.  
  427.       delete fp;     
  428.       base->current_tick=(current_level->tick_counter()&0xff); 
  429.  
  430.       reload_end();
  431.     } else if (current_level)
  432.     {
  433.       
  434.       join_struct *join_list=shm2real(join_struct,base->join_list);
  435.  
  436.       while (!aquire_mem_lock())
  437.       {
  438.     next_process();
  439.     service_net_request();
  440.       }
  441.  
  442.       while (join_list)
  443.       {
  444.     
  445.     view *f=player_list;
  446.     for (;f && f->next;f=f->next);      // find last player, add one for pn
  447.     int i,st=0;
  448.     for (i=0;i<total_objects;i++)
  449.     if (!strcmp(object_names[i],"START"))
  450.     st=i;
  451.  
  452.     game_object *o=create(current_start_type,0,0);
  453.     game_object *start=current_level->get_random_start(320,NULL);
  454.     if (start) { o->x=start->x; o->y=start->y; }
  455.     else { o->x=100; o->y=100; }
  456.  
  457.     f->next=new view(o,NULL,shm2real(join_struct,base->join_list)->client_id);
  458.     strcpy(f->next->name,shm2real(join_struct,base->join_list)->name);
  459.     o->set_controller(f->next);
  460.  
  461.     if (start)
  462.     current_level->add_object_after(o,start);
  463.     else
  464.     current_level->add_object(o);
  465.  
  466.     view *v=f->next;      
  467.  
  468.     v->cx1=5;
  469.     v->cy1=5;
  470.     v->cx2=319-5;
  471.     v->cy2=199-5;
  472.     join_list=shm2real(join_struct,join_list->next);
  473.       }     
  474.       base->join_list=NULL;
  475.       current_level->save(NET_STARTFILE,1);
  476.       base->mem_lock=0;
  477.  
  478.  
  479.       jwindow *j=eh->new_window(0,yres/2,-1,-1,new info_field(WINDOW_FRAME_LEFT,
  480.                                    WINDOW_FRAME_TOP,
  481.                                    0,"Clients are re-syncing, please wait...",NULL));
  482.       eh->flush_screen();
  483.       if (!reload_start()) return ;
  484.  
  485.       // wait for all client to reload the level with the new players
  486.       do  
  487.       { 
  488.     next_process();
  489.       } while (!reload_end());
  490.       eh->close_window(j);
  491.  
  492.     }      
  493.   }
  494. }
  495.  
  496. int client_number() { return local_client_number; }
  497.  
  498.  
  499. void send_local_request()
  500. {
  501.   if (net_installed)
  502.   {
  503.     if (base->join_list)
  504.       base->packet.write_byte(SCMD_RELOAD);
  505.  
  506.     uchar cmd=NFCMD_SEND_INPUT;
  507.  
  508.     if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return ; }    
  509.     if (read(net_in_fd,&cmd,1)!=1) { kill_net(); return ; }    
  510.     if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return ; }    
  511.   } else base->input_state=INPUT_PROCESSING;
  512. }
  513.  
  514. void kill_slackers()
  515. {
  516.   if (net_installed)
  517.   {
  518.     uchar cmd=NFCMD_KILL_SLACKERS;
  519.     if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return ; }    
  520.     if (read(net_in_fd,&cmd,1)!=1) { kill_net(); return ; }        
  521.   }
  522. }
  523.  
  524. int get_inputs_from_server(unsigned char *buf)
  525. {
  526.   if (net_installed && base->input_state!=INPUT_PROCESSING)      // if input is not here, wait on it
  527.   {
  528.     timeval start;
  529.     gettimeofday(&start,NULL);
  530.  
  531.     int total_retry=0;
  532.     jwindow *abort=NULL;
  533.     linked_list input;
  534.     while (base->input_state!=INPUT_PROCESSING)
  535.     { 
  536.       if (!net_installed)  
  537.       { 
  538.     base->input_state=INPUT_PROCESSING; 
  539.     return 1; 
  540.       }
  541.       server_check();
  542.       service_net_request();
  543.  
  544.       timeval now;                   // if this is taking to long, the packet was probably lost, ask for it to be resent
  545.       gettimeofday(&now,NULL);
  546.       if ((((now.tv_sec-start.tv_sec)*100)+(now.tv_usec-start.tv_usec)/10000)>20)
  547.       {
  548. //    fprintf(stderr,"receive timeout %d\n",(((now.tv_sec-start.tv_sec)*100)+(now.tv_usec-start.tv_usec)/10000));
  549.     uchar cmd=NFCMD_INPUT_MISSING;
  550.     if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return  0; }    
  551.     if (read(net_in_fd,&cmd,1)!=1) { kill_net(); return 0; }     // block, so net driver can request input
  552.     gettimeofday(&start,NULL);
  553.     total_retry++;
  554.     if (total_retry==10)    // 2 seconds and nothing
  555.     {
  556.       abort=eh->new_window(0,yres/2,-1,eh->font()->height()*4,
  557.                    new info_field(WINDOW_FRAME_LEFT,
  558.                           WINDOW_FRAME_TOP,
  559.                           0,"Waiting for data...",
  560.                           new button(WINDOW_FRAME_LEFT,
  561.                              WINDOW_FRAME_TOP+eh->font()->height()+5,ID_NET_DISCONNECT,
  562.                              "Disconnect slackers",NULL)),"Error");      
  563.       eh->flush_screen();
  564.     }
  565.       }
  566.       if (abort)
  567.       {
  568.     if (eh->event_waiting())
  569.     {
  570.       event ev;
  571.       do
  572.       {
  573.         eh->get_event(ev);
  574.         if (ev.type==EV_MESSAGE && ev.message.id==ID_NET_DISCONNECT)
  575.         kill_slackers();
  576.         else if (ev.type!=EV_MOUSE_MOVE)  // no need to save mouse move events (likely to be a lot)
  577.         {
  578.           event *e=new event;
  579.           *e=ev;
  580.           input.add_front(e);
  581.         } 
  582.       } while (eh->event_waiting());
  583.  
  584.       eh->flush_screen();
  585.     }
  586.       }
  587.     }
  588.  
  589.     if (abort)
  590.     {
  591.       eh->close_window(abort);
  592.       while (input.first())               // push all the key events
  593.       {
  594.     event *ev=(event *)input.first();
  595.     input.unlink((linked_node *)ev);
  596.     eh->push_event(ev);
  597.       }
  598.     }
  599.   }
  600.  
  601. //  while (!aquire_mem_lock()) service_net_request();
  602.  
  603.   memcpy(base->last_packet.data,base->packet.data,base->packet.packet_size()+base->packet.packet_prefix_size());
  604.   
  605.   int size=base->packet.packet_size();
  606.   memcpy(buf,base->packet.packet_data(),size);
  607.  
  608.   base->packet.packet_reset();
  609.   base->mem_lock=0;
  610.  
  611.   return size;
  612. }
  613.  
  614.  
  615. void server_check()       // read a byte from the net driver, causing the OS to give up the rest of our time-slice
  616. {
  617.   if (net_installed)
  618.   {
  619.     if (base->input_state==INPUT_NET_DEAD)
  620.     { close(net_out_fd); close(net_in_fd); net_installed=0; kill_net(); }
  621.     else
  622.     {
  623.       uchar cmd=NFCMD_BLOCK;
  624.       if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return ; }    
  625.       if (base->input_state==INPUT_NET_DEAD)
  626.       { close(net_out_fd); close(net_in_fd); net_installed=0; kill_net(); }
  627.       else
  628.       {
  629.     if (read(net_in_fd,&cmd,1)!=1) { kill_net(); return ; }  
  630.     if (base->input_state==INPUT_NET_DEAD)
  631.     { close(net_out_fd); close(net_in_fd); net_installed=0; kill_net(); }
  632.     else
  633.       if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return ; }
  634.       }
  635.     }
  636.   }
  637. }
  638.  
  639. int become_server()
  640. {
  641.   if (net_installed)
  642.   {
  643.     uchar cmd=NFCMD_BECOME_SERVER;
  644.     if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return 0; } 
  645.     if (read(net_in_fd,&cmd,1)!=1) { kill_net(); return 0; }     
  646.     
  647.     return 1;
  648.   }
  649.   return 0;
  650. }
  651.  
  652. void read_new_views() { ; }
  653.  
  654.  
  655.